using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Web;
using Blog.Core.Entities;
using Blog.Infrastructure.Configuration;
using Blog.Infrastructure.DataAcces.Repositories.Abstractisations;
using CookComputing.XmlRpc;
using StructureMap;

namespace Blog.Infrastructure.DataAcces.MetaBlog
{
    public class MetaWebLogApi : XmlRpcService, IMetaWeblog, IWordPressApi
    {
        private readonly IArticleRepository articles;
        private readonly IUserRepository users;

        public MetaWebLogApi(IArticleRepository articles, IUserRepository users)
        {
            this.articles = articles;
            this.users = users;
        }

        #region IMetaWeblog Members

        public CategoryInfo[] getCategories(object blogid, string username, string password)
        {
            
            return (from c in articles.Categories()
                    select new CategoryInfo
                               {
                                   title = c.Name,
                                   description = "",
                                   htmlUrl = "",
                                   rssUrl = "",
                                   categoryid = c.Id.ToString()
                               }).ToArray();
        }

        public Post getPost(string postid, string username, string password)
        {
            var postIdAsInt = ParseIntOrThrow(postid, "Invalid PostId  passed");

            return MapArticleToPost(articles.Get(postIdAsInt));
        }

        public Post[] getRecentPosts(object blogid, string username, string password, int numberOfPosts)
        {
            var recentPosts = (from p in articles.Latest(5) select MapArticleToPost(p)).ToArray();
            return recentPosts;
        }

        public bool editPost(string postid, string username, string password, Post post, bool publish)
        {
            var article = articles.Get(int.Parse(postid));
            if (article == null)
            {
                return false;
            }

            article.Title = post.title;
            article.Content = post.description;
            article.Date = DateTime.Now;

            article.SetCategories(post.categories);
            articles.Save(article);

            return true;
        }

        public string newPost(object blogid, string username, string password, Post post, bool publish)
        {
            var article = new Article
                              {
                                  Title = post.title,
                                  Content = post.description,
                                  Date = DateTime.Now
                              };
            article.SetCategories(post.categories);

            articles.Save(article);

           return article.Id.ToString();
        }

        public mediaObjectInfo newMediaObject(object blogid, string username, string password, mediaObject mediaobject)
        {
           var imageUploadPath = ObjectFactory.GetInstance<ISettings>().ImageUploadPath;

           
            var imagePhysicalPath = HttpContext.Current.Server.MapPath(imageUploadPath) + mediaobject.name;

            var pathOnly = Path.GetDirectoryName(imagePhysicalPath).Replace("/", "\\");

            if (!Directory.Exists(pathOnly))
                Directory.CreateDirectory(pathOnly);

            if (mediaobject.bits != null)
            {
                var ms = new MemoryStream(mediaobject.bits);
                var bitmap = new Bitmap(ms);
                bitmap.Save(imagePhysicalPath);
            }

            return new mediaObjectInfo { url = VirtualPathUtility.ToAbsolute(imageUploadPath) + mediaobject.name };
        }

        public bool deletePost(string appKey, string postid, string username, string password, bool publish)
        {
            var postIdAsInt = ParseIntOrThrow(postid, "Invalid PostId");

            articles.Delete(postIdAsInt);

            return true;
        }

        public BlogInfo[] getUsersBlogs(string appKey, string username, string password)
        {
           return new[]
                       {
                           new BlogInfo
                               {
                                   blogid = "",
                                   blogName = "GlassBird",
                                   url = "www.GlassBird.com"
                               }
                       };
        }

        #endregion

        #region IWordPressApi Members

        public int newPage(string blog_id, string username, string password, Post content, bool publish)
        {
            var article = new Article
            {
                Title = content.title,
                Content = content.description,
                Date = DateTime.Now
            };
            article.SetCategories(content.categories);

            articles.Save(article);

            return (int)article.Id;
        }

        public int newCategory(string blogid, string username, string password, WordpressCategory category)
        {
           return articles.NewCategory(category);
        }

        public int editPage(string blog_id, string page_id, string username, string password, Post content, bool publish)
        {
          
           return 0;
        }

        public Post[] getPages(string blog_id, string username, string password, int numberOfPosts)
        {
          return (from p in articles.Latest(5) select MapArticleToPost(p)).ToArray();
        }

        public Post getPage(string blog_id, string page_id, string username, string password)
        {
            var postIdAsInt = ParseIntOrThrow(page_id, "Invalid PostId");

            return MapArticleToPost(articles.Get(postIdAsInt));
        }

        public bool deletePage(string blog_id, string username, string password, string page_id)
        {
            int postIdAsInt = ParseIntOrThrow(page_id, "Invalid PostId");

            articles.Delete(postIdAsInt);

            return true;
        }

        #endregion

        private Post MapArticleToPost(Article page)
        {
            return new Post
                       {
                           title = page.Title,
                           description = page.Content,
                           dateCreated = page.Date,
                           categories = new string[1],
                           postid = page.Id,
                           userid = "1"
                       };
        }

        private int ParseIntOrThrow(string strId, string throwInCaseOfError)
        {
            int postIdAsInt = 0;

            if (!int.TryParse(strId, out postIdAsInt))
                throw new XmlRpcException(throwInCaseOfError);

            return postIdAsInt;
        }
    }
}